﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RaytracerLib.MathLib.RootFinders
{
    public class CentralDifferenceMethod
    {
        private double m_h;
        private Func<double, double> m_func;

        public CentralDifferenceMethod()
            : base()
        {
        }
        
        public CentralDifferenceMethod(Func<double, double> a_func, 
            double a_h = Constants.DOUBLE_PRECISION * 2)
        {
            m_h = a_h;
            m_func = a_func;
        }

        public double Derive1(double a_x)
        {
            return (m_func(a_x + m_h) - m_func(a_x - m_h)) / (2 * m_h);
        }

        public double Derive2(double a_x)
        {
            return (m_func(a_x + m_h) - 2 * m_func(a_x) + 
                m_func(a_x - m_h)) / (m_h * m_h);
        }

        public static  Func<double, double> Derive1(
            Func<double, double> a_func, double a_h)
        {
            CentralDifferenceMethod cdm = 
                new CentralDifferenceMethod(a_func, a_h);

            return (x) =>
            {
                return cdm.Derive1(x);
            };
        }

        public static Func<double, double> Derive2(
            Func<double, double> a_func, double a_h)
        {
            CentralDifferenceMethod cdm = 
                new CentralDifferenceMethod(a_func, a_h);

            return (x) =>
            {
                return cdm.Derive2(x);
            };
        }

        public static Func<double, double> Derive2(Func<double, double> a_func, 
            Func<double, double> a_d1, double a_h)
        {
            CentralDifferenceMethod cdm = 
                new CentralDifferenceMethod(a_d1, a_h);

            return (x) =>
            {
                return cdm.Derive1(x);
            };
        }
    }
}
